logo头像
Snippet 博客主题

Vue.js 2.5新特性介绍

TypeScript

TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。2012年十月份,微软发布了首个公开版本的TypeScript,在2013年6月19日,微软发布了TypeScript 0.9的正式版本,到目前为止,TypeScript已发展到2.x版本,相关资料可以查看W3C TypeScript入门

安装TypeScript

安装TypeScript主要有两种方式:

  • 通过npm方式安装(Node.js包管理器)
  • 安装TypeScript的Visual Studio插件
    说明:Visual Studio2016和Visual Studio 2013 Update 2默认包含了TypeScript。npm安装的命令如下:
1
npm install -g typescript

##创建TypeScript文件
在编辑器中新建一个greeter.ts文件,并输入以下JavaScript代码:

1
2
3
4
5
6
7
function greeter(person) {
return "Hello, " + person;
}
var user = "Jane User";
document.body.innerHTML = greeter(user);

上面的代码直接输出“hello Jane User”。

编译代码

在在命令行中运行TypeScript编译器即可编译代码:

1
tsc greeter.ts

运行TypeScript web程序

现在在greeter.html中输入以下代码:

1
2
3
4
5
6
7
<!DOCTYPE html>
<html>
<head><title>TypeScript Greeter</title></head>
<body>
<script src="greeter.js"></script>
</body>
</html>

在浏览器中打开greeter.html即可去运行第一个TypeScript web应用程序demo!
关于更多的介绍请查看TypeScript

Vue.js 2.5新特性

Vue 2.5 Level E 已发布,在原来2.x的基础上做了很多相应改进和对 bug 的修复,目前 2.5 系列最新的版本为 2.5.2。如果读者希望全面的了解Vue 2.5的内容,可以通过查看Vue 2.5发布说明来获取详细的介绍。针对官方的介绍和网上搜集的资料,本次2.5版本主要做了如下几方面的改进:

  • 更好的 TypeScript 集成
  • 更好的错误处理
  • 更好地支持单文件组件中的功能组件
  • 与环境无关的服务端渲染

读者可以通过下面的链接查看原文介绍:
TypeScript 声明改进
further improve Vue type declarations for canonical usage (#6391) db138e2

错误处理和报告
improve error handling with new errorCaptured hook b3cd9bc [Details]

improve template expression error message e38d006, closes #6771

improve option type checks b7105ae

功能组件
compiled templates for functional component support ea0d227

scoped CSS support for functional components 050bb33

服务器端渲染

renderToString now returns a Promise if no callback is passed f881dd1, closes #6160

add shouldPrefetch option (same signature as shouldPreload) 7bc899c, closes #5964

auto-remove initial state embed script if in production (#6763) 2d32b5d, closes #6761

now ships an environment-agnostic build of the server renderer in vue-server-renderer/basic.jsc5d0fa0 Details

TypeScript改进

自Vue2.0发布以来,一直有开发者提出请求,希望能更好地集成TypeScript。从那时起,我们已经为大多数核心库(vue,vue - routervuex)加入了官方的TypeScript类型声明。然而,当使用开箱即用的Vue API时,目前的集成还是有所欠缺。例如:TypeScript不能轻易地推断出Vue使用的默认基于对象的API中的this类型。为了使我们的Vue代码与TypeScript更好地协作,我们需要使用vue-class-component装饰器,它允许我们使用基于类的语法来写Vue组件。

对于喜欢基于类的API的用户,这可能够好了,但还是有点不足,只是为了类型判断,用户就得使用不同的API。这也使得现有的Vue代码库迁移到TypeScript更加困难。

今年的早些时候,TypeScript引入了一些新特性,能使TypeScript更好地理解基于对象字面量的API,这也使得改进Vue的类型声明更具可能。来自TypeScript团队的Daniel Rosenwasser发起了一个雄心勃勃的PR计划。使用TypeScript后,将会有如下的好处:

  • 使用默认的Vue API时,对this的正确类型推断。在单文件组件中同样有效!
  • 基于组件的props配置的的props的类型推断。
  • 更重要的是,这些改进也会使原生JavaScript用户受益!,如果你正在使用VSCode且安装了优秀的Vetur扩展,在Vue组件中使用原生JavaScript时,你会获得十分完善的自动补全提示甚至是类型提示!这是因为vue-language-server,这个分析Vue组件的内部包,可以利用TypeScript编译器来提取关于你代码的更多信息。此外,任何支持语言服务协议的的编辑器都可以利用vue-language-server来提供类似的功能。

说明:注意:TypeScript 用户还应将以下包更新为最新版本从而兼容类型声明:vue-router,vuex,vuex-router-sync 和 vue-class-component。

这里写图片描述

错误提示

在2.4及更早版本中,通常使用全局 config.errorHandleroption 来处理应用程序中的意外错误。当然,还可以使用renderError 组件选项来处理渲染函数中的错误。

而在新版本中,vue引入了errorCaptured 钩子,具有此钩子的组件捕获其子组件树(不包括其自身)中的所有错误(不包括在异步回调中调用的那些)。这和React的思想是一致的。

要利用 errorCaputerd,可以封装一个通用组件,来包含其他的业务组件,来捕获业务组件内的异常,并做对应的展示处理。下面列一个官方给的简单示例,封装一个通用组件(ErrorBoundary)来包含和处理其他业务组件(another component)的异常。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Vue.component('ErrorBoundary', {
data: () => ({ error: null }),
errorCaptured (err, vm, info) {
this.error = `${err.stack}\n\nfound in ${info} of component`
return false
},
render (h) {
if (this.error) {
return h('pre', { style: { color: 'red' }}, this.error)
}
// ignoring edge cases for the sake of demonstration
return this.$slots.default[0]
}
})
1
2
3
<error-boundary>
<another-component />
</error-boundary>

errorCaputed参数传递主要有如下的特性:

  • 如果定义了全局的 errorHandler,所有的异常还是会传递给 errorHadnler,如果没有定义
    errorHandler,这些异常仍然可以报告给一个单独的分析服务。
  • 如果一个组件上通过继承或父组件定义了多个 errorCapured 钩子函数,这些钩子函数都会收到同样的异常信息。
  • 可以在 errorCapured 钩子内 return false 来阻止异常传播,表示:该异常已经被处理,可忽略。而且,也会阻止其他的 errorCapured 钩子函数和全局的 errorHandler 函数触发这个异常。

    SFC 函数式组件

通过 vue-loader v13.3.0 或以上版本,支持在单文件组件内定义一个“函数式组件”,且支持模板编译、作用域 CSS 和 热部署等功能。

函数式组件的定义,需要在 template 标签上定义 functional 属性来声明。且模板内的表达式的执行上下文是 函数式声明上下文,所以要访问组件的属性,需要使用 props.xxx 来获取。例子见下:

1
2
3
<template functional>
<div>{{ props.msg }}</div>
</template>

与环境无关的服务端渲染(SSR 环境)

使用 vue-server-renderer 来构建 SSR 应用时,默认是需要一个 Node.js 环境的,使得一些像 php-v8js 或 Nashorn 这样的 JavaScript 运行环境下无法运行。v2.5 中对此进行了完善,使得上述环境下都可以正常运行 SSR 应用。

在 php-v8js 和 Nashorn 中,在环境的准备阶段需要模拟 global 和 process 全局对象,并且需要单独设置 process 的环境变量。需要设置 process.env.VUE_ENV 为 “server”,设置 process.env.NODE_ENV 为 “development” 或 “production”。

另外,在 Nashorn 中,还需要用 Java 原生的 timers 为 Promise 和 settimeout 提供一个 polyfill。官方给出了一个在 php-v8js 中的使用示例,如下:

1
2
3
4
5
6
7
8
9
10
<?php
$vue_source = file_get_contents('/path/to/vue.js');
$renderer_source = file_get_contents('/path/to/vue-server-renderer/basic.js');
$app_source = file_get_contents('/path/to/app.js');
$v8 = new V8Js();
$v8->executeString('var process = { env: { VUE_ENV: "server", NODE_ENV: "production" }}; this.global = { process: process };');
$v8->executeString($vue_source);
$v8->executeString($renderer_source);
$v8->executeString($app_source);
?>
1
2
3
4
5
6
7
8
9
10
11
12
// app.js
var vm = new Vue({
template: `<div>{{ msg }}</div>`,
data: {
msg: 'hello'
}
})
// exposed by vue-server-renderer/basic.js
renderVueComponentToString(vm, (err, res) => {
print(res)
})

Vue.js 这款渐进式的 JavaScript 框架自 2013 年发布至今,其简洁的语法设计、轻量快速的特点深受技术社区喜爱,在国内外都获得了非常广泛的应用及拓展,比如饿了么的开源组件库 Element UI 即是 根据Vue 开发的,而阿里巴巴的 Weex 与 Vue 也多有合作,而美团点评的mpVue也是比较出色的一款框架。

v-on 修饰符

键值 key 自动修饰符

在 Vue v2.5 之前的版本中,如果要在 v-on 中使用没有内置别名的键盘键值,要么直接使用 keyCode 当修饰符(@keyup.13=”foo”),要么需要使用 config.keyCodes 来为键值注册别名。在 v2.5中,你可以直接使用合法的键值 key 值(参考MDN中的 KeyboardEvent.key)作为修饰符来串联使用它。如下:

1
<input @keyup.page-down="onPageDown">

上述例子中,事件处理函数只会在 $event.key === ‘PageDown’ 时被调用。
注意:现有键值修饰符仍然可用。在IE9中,一些键值(.esc 和 方向键的 key)不是一致的值,如果要兼容 IE9,需要按 IE9 中内置的别名来处理。

.exact 修饰符

新增了一个 .exact 修饰符,该修饰符应该和其他系统修饰符(.ctrl, .alt, .shift and .meta)结合使用,可用用来区分一些强制多个修饰符结合按下才会触发事件处理函数。如下:

1
2
3
4
5
<!-- 当 Alt 或 Shift 被按下也会触发处理函数 -->
<button @click.ctrl="onClick">A</button>
<!-- 只有当 Ctrl 被按下,才会触发处理函数 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

简化 Scoped Slots 的使用

之前,如果要在 template 标签上使用 scope 属性定义一个 scoped slot,可以像下面这样定义:

1
2
3
4
5
<comp>
<template scope="props">
<div>{{ props.msg }}</div>
</template>
</comp>

在 v2.5 中,scope 属性已被弃用(仍然可用,但是会爆出一个警告,就像本文文首的那样),我们使用 slot-scope 属性替代 scope 属性来表示一个 scoped slot,且 slot-scope 属性除了可以被用在 template 上,还可以用在标签元素和组件上。如下:

1
2
3
4
5
<comp>
<div slot-scope="props">
{{ props.msg }}
</div>
</comp>

注意:这次的调整,表示 slot-scope 已经是一个保留属性了,不能再被单独用在组件属性上了。

Inject 新增默认值选项

本次调整中,Injections 可以作为可选配置,并且可以声明默认值。也可以用 from 来表示原属性。

1
2
3
4
5
6
7
8
export default {
inject: {
foo: {
from: 'bar',
default: 'foo'
}
}
}

与属性类似,数组和对象的默认值需要使用一个工厂函数返回。

1
2
3
4
5
6
7
8
export default {
inject: {
foo: {
from: 'bar',
default: () => [1, 2, 3]
}
}
}

附:美团小程序框架mpVue

支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者

上一篇